package com.cloudmind.filetransfer;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.Xml;

public class CldUpdate {
	private final static String TAG = "CldUpdate";
	private String addr = null;
	private Handler handler = null;
	private boolean running = true;
	private updateThread update;
	private String currentVersion = null;
	private String updateVersion = null;
	private String updateFileName = null;

	private DownloadManager downloadManager;
	private long downloadId = 0;
	private CldReceiver cRec;
	
	public static final int MSG_SHOW_UPDATE = 100;

	public CldUpdate(String addr, String version, Handler handler){
		currentVersion = version;
		this.addr = addr;
		this.handler = handler;

		cRec = new CldReceiver();
	}

	public void start() {
		Log.i(TAG,"start");
		running = true;

		if(addr != null && handler != null){
			update = new updateThread();
			update.start();
		}
	}

	private class updateThread extends Thread {
		private InputStream input = null;
		
		public void run() {				
			try {
				Log.i(TAG,"run");
				String addr_xml = "http://" + addr + "/upgrade/client/vernier_file_update.xml";
				URL url = new URL(addr_xml);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(10 * 1000);
				conn.setReadTimeout(10 * 1000);
				
				try{
					input = conn.getInputStream();
					if(input != null){
						parseUpdateXml(input);
						Log.e(TAG,"111 currentVersion : " + currentVersion);	
						Log.e(TAG,"111 updateVersion : " + updateVersion);
						boolean versionUpdateflag = versionUpdateCheck(currentVersion, updateVersion);
						Log.e(TAG,"222 versionUpdateflag : " + versionUpdateflag);
						if(versionUpdateflag){
							Message m = new Message();
							m.setTarget(handler);
							m.what = MSG_SHOW_UPDATE;
							Bundle strings = new Bundle();
							strings.putString("updateVersion", updateVersion);
							m.obj = strings;
							handler.sendMessage(m);
			        	}  					
					}
				} catch(IOException e) {
					Log.e(TAG,"connect cldauth server failed");		
				}
			}catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		private void parseUpdateXml(InputStream input) throws XmlPullParserException, IOException{
			XmlPullParser parser = Xml.newPullParser(); 
			try{
				parser.setInput(input, "UTF-8");
			}catch(XmlPullParserException e){
				return;
			}
			boolean isVernier = false;

			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) { 
				switch (eventType) {  
	        		case XmlPullParser.START_DOCUMENT:  
						//Log.v(TAG,"START_DOCUMENT :" + parser.getName());
						break;
					case XmlPullParser.START_TAG:						
						if(parser.getName().equals("platform")){
							if(parser.getAttributeValue(null, "version").equals("EquiBox-5") &&
									parser.getAttributeValue(null, "type").equals("Vernier_file")){								
								isVernier = true;
							}else{
								isVernier = false;
							}
						}else if(parser.getName().equals("version")){
							if(isVernier == false){
								break;
							}
							if(parser.getAttributeValue(null, "latest") != null){
								updateVersion = parser.getAttributeValue(null, "latest");
							}
							if(parser.getAttributeValue(null, "value") != null){
								if(parser.getAttributeValue(null, "value").equals(updateVersion)){							
									updateFileName = parser.getAttributeValue(null, "url");
								}
							}	
						}
						break;
					case XmlPullParser.END_TAG:  
						if(parser.getName().equals("platform")){
							isVernier = false;
						}
						break;
					default:
						break;
				}
				eventType = parser.next();
			}

			Log.i(TAG,"update version :" + updateVersion);
			Log.i(TAG,"update file name :" + updateFileName);
		}


		boolean versionUpdateCheck(String curVersion, String serVersion) {
			/*
			 * version module is vx.y.z, x mean product version, y mean release
			 * version, z mean debug version
			 */
			boolean ret = false;
			String str1,str2;
			int pos1 = 0,pos2 = 0;
			int value1,value2;
			boolean equal = false;
			
			if((curVersion != null) && (serVersion != null))
			{
				curVersion = curVersion.substring(1);
				while((curVersion.indexOf(".")!=-1)&&(serVersion.indexOf(".")!=-1))
				{
					pos1 = curVersion.indexOf(".");
					pos2 = serVersion.indexOf(".");
					str1 = curVersion.substring(0, pos1);
					str2 = serVersion.substring(0, pos2);
					
					if(!str1.equalsIgnoreCase(str2)){
						equal = false;
						value1 = Integer.parseInt(str1);
						value2 = Integer.parseInt(str2);
						if(value1 < value2){
							ret = true;
						}
						break;
					}else{
						equal = true;
					}
					
					curVersion = curVersion.substring(pos1+1);
					serVersion = serVersion.substring(pos2+1);
				}
				
			}

			/*last position*/
			if(equal == true){
				if(!curVersion.equalsIgnoreCase(serVersion)){
					value1 = Integer.parseInt(curVersion);
					value2 = Integer.parseInt(serVersion);
					if(value1 < value2){
						ret = true;
					}
				}
			}
			
			return ret;
		}
	}

	public void startDownload(Context context, String title){
		String folder_name = "vernier_file_update";
		File folder = Environment.getExternalStoragePublicDirectory(folder_name);
		if(folder.exists() && folder.isDirectory()){
	        File[] files = folder.listFiles();
	        for (int i = 0; i < files.length; i++) {
	            File f = files[i];
				f.delete();
	        }
		}else{
			folder.mkdirs();
		}
		
		String url = "http://" + addr + "/upgrade/client/" + updateFileName;
		Log.i(TAG,"download url : " + url);

		DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
		request.setDestinationInExternalPublicDir(folder_name, updateFileName);
		request.setTitle(title);
		request.setDescription(folder_name);
		request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
		request.setVisibleInDownloadsUi(false);
		request.setMimeType("application/vnd.android.package-archive");
		downloadManager = (DownloadManager)(context.getSystemService(context.DOWNLOAD_SERVICE));
		context.registerReceiver(cRec, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
		downloadId = downloadManager.enqueue(request);	
		return;	
	}

	class CldReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String filename =null;    	
			
			String action = intent.getAction();  
		    if(action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {  
		    	long intentdownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
		    	if(intentdownloadId == downloadId){
		    		Query query = new DownloadManager.Query().setFilterById(intentdownloadId); 
		    		Cursor cursor = downloadManager.query(query); 
		    		
		    		if (cursor != null && cursor.moveToNext()) {
		    			try{
		    				filename = cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_FILENAME));
		    				if(filename != null){
		    					install(context, filename);
		    				}else{
		    					Log.e(TAG,"DownloadManager failed");
		    				}
		    			}catch(IllegalArgumentException e){
		    				e.printStackTrace();
		    			}
		            }
		    		cursor.close();
		    	}	     
		    }
		}
	}
	
	public static boolean install(Context context, String filePath) {
		Intent i = new Intent(Intent.ACTION_VIEW);
		File file = new File(filePath);
		i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		if (file != null && file.length() > 0 && file.exists() && file.isFile()) {
			i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
			context.startActivity(i);
			return true;
		}
		return false;
	}
}
